package com.tamecode.chapter06.sec3;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @author liqc
 * @version 1.0.0
 * @since 1.0.0
 */
public class DESUtils {

    // ① 指定 DES 加密解密所用的密钥
    private static Key key;
    private static String KEY_STR = "myKey";
    static {
        try {
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            generator.init(new SecureRandom(KEY_STR.getBytes()));
            key = generator.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * ②对字符串进行 DES 加密，返回 BASE64 编码的加密字符串
     * @param str
     * @return
     */
    public static String getEncryptString(String str) {
        BASE64Encoder base64Encoder = new BASE64Encoder();
        try {
            byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptStrBytes = cipher.doFinal(bytes);
            return base64Encoder.encode(encryptStrBytes);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * ③对BASE64编码的加密字符串进行解密，返回解密后的字符串
     * @param str
     * @return
     */
    public static String getDecryptString(String str) {
        BASE64Decoder base64Decoder = new BASE64Decoder();
        try {
            byte[] bytes = base64Decoder.decodeBuffer(str);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decryptStrBytes = cipher.doFinal(bytes);
            return new String(decryptStrBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * ④对入参的字符串进行加密，打印出来加密后的串
     * @param args
     */
    public static void main(String[] args) {
        if (args == null || args.length < 1) {
            System.out.println("error");
        } else {
            for (String arg : args) {
                System.out.println(arg + ": " + getEncryptString(arg));
            }
        }
    }

}
